import './plot';
import './entity/app';
import { loadPlayer } from './data';

// 常量定义
const CHECKPOINT_PREFIX: string = '旋转圆圈-';
const ADMIN_DIALOG_CONTENT: string = '管理员特权';
const ADMIN_OPTIONS: string[] = [
    '变大',
    '变小',
    '大小还原',
    '变色',
    '隐藏',
    '显示',
    '发光',
    '还原发光',
    '飞行',
    '取消飞行',
    '走路速度增加',
    '走路速度恢复',
    '奔跑速度增加',
    '奔跑速度恢复',
    '跳跃力度增加',
    '跳跃力度恢复',
    '二段跳力度增加',
    '二段跳力度恢复',
    '潜行速度增加',
    '潜行速度恢复',
    '飞行速度增加',
    '飞行速度恢复',
];
const TEST_PLAYER: string[] = [
    '50041641',
    '283433385369436',
    '12764309',
    '12937631',
    '313299988179674',
    '13420874',
    '13157876',
]; // 管理员的Id

// 辅助函数：创建粒子效果
async function createCheckpointParticles(entity: GameEntity) {
    Object.assign(entity, {
        particleRate: 20,
        particleLimit: 100,
        particleLifetime: 3,
        particleLifetimeSpread: 0.9,
        particleColor: [
            new GameRGBColor(0, 0.4, 0.3),
            new GameRGBColor(0, 200 / 320, 128 / 255),
            new GameRGBColor(0, 200 / 320, 128 / 255),
            new GameRGBColor(0, 180 / 320, 128 / 255),
            new GameRGBColor(0, 0, 0),
        ],
        particleSize: [15, 10, 2, 1, 0.5],
        particleVelocity: new GameVector3(0, 7, 0),
    });
    setTimeout(() => {
        Object.assign(entity, {
            particleRate: 0,
        });
    }, 1500);
}

// 辅助函数：处理管理员权限
async function handleAdminPrivileges(entity: GamePlayerEntity) {
    if (
        !TEST_PLAYER.includes(entity.player.userId) &&
        !((await entity.player.getMiaoShells()) >= 10)
    ) {
        return;
    }

    const result = await entity.player.dialog({
        type: GameDialogType.SELECT,
        content: ADMIN_DIALOG_CONTENT,
        options: ADMIN_OPTIONS,
    });

    if (!result) {
        return;
    }

    switch (result.index) {
        case 0:
            entity.player.scale += 0.15;
            break;
        case 1:
            entity.player.scale -= 0.15;
            break;
        case 2:
            entity.player.scale = 1;
            break;
        case 3: // 变色
            const colors = [
                new GameRGBColor(1, 0, 0),
                new GameRGBColor(0, 1, 0),
                new GameRGBColor(0, 0, 1),
                new GameRGBColor(1, 1, 0),
                new GameRGBColor(0, 1, 1),
                new GameRGBColor(1, 0, 1),
                new GameRGBColor(1, 1, 1),
            ];
            let i = 0;
            const intervalId = setInterval(() => {
                entity.player.color.set(colors[i].r, colors[i].g, colors[i].b);
                i = (i + 1) % colors.length;
            }, 500);
            setTimeout(() => clearInterval(intervalId), colors.length * 500);
            break;
        case 4:
            entity.player.invisible = true;
            break;
        case 5:
            entity.player.invisible = false;
            break;
        case 6:
            entity.player.emissive = 1;
            break;
        case 7:
            entity.player.emissive = 0;
            break;
        case 8:
            entity.player.canFly = true;
            break;
        case 9:
            entity.player.canFly = false;
            break;
        case 10:
            entity.player.walkSpeed += 0.1;
            break;
        case 11:
            entity.player.walkSpeed = 0.22;
            break;
        case 12:
            entity.player.runSpeed += 0.1;
            break;
        case 13:
            entity.player.runSpeed = 0.4;
            break;
        case 14:
            entity.player.jumpPower += 0.1;
            break;
        case 15:
            entity.player.jumpPower = 0.96;
            break;
        case 16:
            entity.player.doubleJumpPower += 0.1;
            break;
        case 17:
            entity.player.doubleJumpPower = 0.9;
            break;
        case 18:
            entity.player.crouchSpeed += 0.1;
            break;
        case 19:
            entity.player.crouchSpeed = 0.1;
            break;
        case 20:
            entity.player.flySpeed += 0.5;
            break;
        case 21:
            entity.player.flySpeed = 2;
            break;
    }
}

world.addCollisionFilter('player', 'player');

world.onPlayerJoin(async ({ entity }: GamePlayerEntityEvent) => {
    // 加载玩家数据
    await loadPlayer(entity);
    console.log(
        entity.player.name +
            ' 合并数据库后的数据： ' +
            JSON.stringify(entity.data)
    );
    // entity.position.set(186, 7, 152);
    entity.startTime = Date.now();
    entity.player.canFly = false;
    entity.player.directMessage('开始计时');

    entity.onFluidEnter(() => {
        entity.position.copy(entity.player.spawnPoint);
        entity.player.directMessage('落水返回最近的存档点，继续加油qwq~');
    });

    entity.onVoxelContact(({ voxel }) => {
        if (voxel === voxels.id('barrier')) {
            entity.position.copy(entity.player.spawnPoint);
        }
    });
});

// 获取所有存档点实体
const checkpointEntities: GameEntity[] = world
    .querySelectorAll('*')
    .filter((e) => e.id.startsWith(CHECKPOINT_PREFIX));

// 初始化存档点
for (const checkpoint of checkpointEntities) {
    checkpoint.collides = true;
    checkpoint.fixed = true;
    checkpoint.meshScale = checkpoint.meshScale.scale(1);

    checkpoint.onEntityContact(async ({ other }) => {
        if (other.player) {
            if (checkpoint !== other.point) {
                other.player.directMessage('到达新的重生点 继续加油qwq～');

                other.player.spawnPoint = new GameVector3(
                    checkpoint.position.x,
                    checkpoint.position.y + 3,
                    checkpoint.position.z
                );
                other.point = checkpoint;
                createCheckpointParticles(checkpoint);
            }
        }
    });
}

async function fireball(x: number, y: number, z: number) {
    // 单独一个火球的代码
    const random1 = Math.random(),
        random2 = Math.random(),
        random3 = Math.random(),
        random4 = Math.random();
    const fire = world.createEntity({
        mesh: '',
        gravity: false,
        collides: false,
        fixed: true,
        position: new GameVector3(x, y, z),
        particleSize: [8, 6, 4, 2],
        particleRate: 1,
        particleLifetime: 0.07,
        particleVelocity: new GameVector3(0, 0, 0),
        particleVelocitySpread: new GameVector3(45, 45, 45),
        particleDamping: -1,
        particleRateSpread: 500,
        particleColor: [
            new GameRGBColor(random1 * 40, random2 * 2, random3 * 2),
        ],
    }) as GameEntity;
    fire.meshInvisible = true;
    fire.particleRate = 0;
    for (let x = 0; x < 64; x++) {
        await sleep(20);
        fire.position.y++;
    }
    await sleep(4000);
    fire.addTag('fire');
    fire.particleRate = 1;
    fire.particleLifetime = 1;
    if (random4 < 0.33) {
        fire.particleColor = [
            new GameRGBColor(random1 * 40, random2 * 2, random3 * 2),
        ];
    } else if (random4 < 0.66) {
        fire.particleColor = [
            new GameRGBColor(random1 * 2, random2 * 30, random3 * 2),
        ];
    } else {
        fire.particleColor = [
            new GameRGBColor(random1 * 2, random2 * 2, random3 * 40),
        ];
    }
    await sleep(2000);
    world.querySelectorAll('.fire').forEach((e) => {
        if (!e.isPlayer) {
            e.destroy();
        }
    });
    fireball(x, y, z);
}
const data: number[][] = [
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0,
    ],
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0,
    ],
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0,
    ],
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0,
    ],
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0,
    ],
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0,
    ],
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0,
    ],
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0,
    ],
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0,
    ],
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0,
    ],
    [
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 1, 0, 0,
    ],
]; // 存储烟花图案的数组，1表示有烟花，0表示无烟花
for (let x = 0; x < data.length; x++) {
    for (let z = 0; z < data[x].length; z++) {
        if (data[x][z] === 1) {
            //fireball(100 - x * 3, 40, z * 3);  // 空中的横着的烟花
            fireball(z * 3, 100 - x * 3, 40); // 空中竖着的烟花
        }
    }
}

world.onPress(async ({ entity, button }: GameInputEvent) => {
    if (button === 'action0') {
        await handleAdminPrivileges(entity);
    } else if (button === 'action1') {
        // entity.player.dialog({
        //     type: GameDialogType.TEXT,
        //     content: `已用时${(Date.now() - entity.startTime) / 1000}秒`,
        // })
    }
});
